﻿#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <assert.h>
#include <vector>
#include <map>
using namespace std;

//struct Point
//{
//	int _x;
//	int _y;
//};
//
//class Date
//{
//public:
//	Date(int year = 1, int month = 1, int day = 1)
//		:_year(year),
//		_month(month),
//		_day(day)
//	{
//		cout << "Date(int year, int month, int day)" << endl;
//	}
//
//	Date(const Date& d)
//		:_year(d._year)
//		, _month(d._month)
//		, _day(d._day)
//	{
//		cout << "Date(const Date& d)" << endl;
//	}
//
//	~Date()
//	{
//		cout << "~Date() " << endl;
//
//	}
//
////private:
//	int _year;
//	int _month;
//	int _day;
//};
//
//void test01()
//{
//	// C++98支持的
//	int a[] = { 1,2,3,4 };
//	int b[20] = { 0 };
//	Point p = { 1,2 };
//
//	// C++11支持的
//	// 内置类型支持
//	int k = { 1 };
//	int k2 = 1;
//
//	// 自定义类型支持
//	// 这里本质是用{ 2025, 1, 1}构造一个Date临时对象
//	// 临时对象再去拷贝构造d1，编译器优化后合二为一变成{ 2025, 1, 1}直接构造初始化d1
//	// 运行一下，我们可以验证上面的理论，发现是没调用拷贝构造的
//	Date d1 = { 2025, 1, 1 };
//	Date d20(2025, 1, 1);
//
//	// 这里d2引用的是{ 2024, 7, 25 }构造的临时对象
//	const Date& d2 = { 2024,7,25 };
//	// 需要注意的是C++98支持单参数时类型转换，也可以不用{}
//	Date d3 = { 2025 }; // C++11
//	Date d4 = 2025;    // C++98
//	string str = "1111";
//
//	// 可以省略掉=
//	Point pp{ 2,6 };
//	int xx{ 9 };
//	Date d5{ 5,6 };
//	const Date& d6{ 7 };
//
//	// 不支持，只有{}初始化，才能省略=
//	//Date d7 2024;
//
//	vector<Date> v;
//	v.push_back(d1);
//	v.push_back(Date(2025, 1, 1));
//	// 比起有名对象和匿名对象传参，这里{}更有性价比
//	v.push_back({ 2025, 1, 1 });
//	map<string, string> dict;
//	dict.insert({ "xxx", "yyyy" });
//
//	// 构造+拷贝构造+优化
//	//vector<int> v1 = { 1,2,3,4 };
//	//vector<int> v2 = { 10,20,30,1,1,1,1,1,1,1,1,1};
//	//const vector<int>& v4 = { 10,20,30,1,1,1,1,1,1,1,1,1 };
//
//	/*vector<int> v = { 1,2,3,4 };
//	vector<int> v{ 1,2,3,4 };*/
//
//	vector<int> v1{ 1,2,3,4 };
//	vector<int> v2{ 10,20,30,1,1,1,1,1,1,1,1,1 };
//	const vector<int>& v4 { 10,20,30,1,1,1,1,1,1,1,1,1 };
//
//	// 构造
//	vector<int> v3({ 10,20,30,1,1,1,1,1,1,1,1,1 });
//
//	initializer_list<int> il1 = { 10, 20, 30, 1, 1, 1, 1, 1, 1, 1, 1, 1};
//	int aa1[] = { 10, 20, 30, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
//
//	// initializer_list + {}pair初始化隐式类型转换
//	map<string, string> ddict = { { "xxx", "yyyy" }, { "sort", "zzzz" } };
//	map<string, int> dddict = { {"bbb",1},{"kkk",9} };
//
//}
//
//void test02()
//{
//	// 左值：可以取地址
//	// 以下的p、b、c、*p、s、s[0]就是常见的左值
//	int* p = new int(0);
//	int b = 1;
//	const int c = b;
//	*p = 10;
//	string s("111111");
//	s[0] = 'x';
//
//	cout << &c << endl;
//	cout << (void*) & s[0] << endl;
//
//	// 左值引用给左值取别名
//	int& r1 = b;
//	int*& r2 = p;
//	int& r3 = *p;
//	string& r4 = s;
//	char& r5 = s[0];
//
//	// 右值：不能取地址
//	double x = 1.1, y = 2.2;
//	// 以下几个10、x + y、fmin(x, y)、string("11111")都是常见的右值
//	10;
//	//x + y;
//	//fmin(x, y);
//	//string("11111");
//
//	//cout << &10 << endl;
//	//cout << &(x + y) << endl;
//	//cout << &fmin(x, y) << endl;
//	//cout << &string("11111") << endl;
//
//	// 右值引用给右值取别名
//	int&& rr1 = 10;
//	double&& rr2 = x + y;
//	double&& rr3 = fmin(x, y);
//	string&& rr4 = string("11111");
//
//	// 左值引用不能直接引用右值，但是const左值引用可以引用右值
//	const int& rx1 = 10;
//	const double& rx2 = x + y;
//	const double& rx3 = fmin(x, y);
//	const string& rx4 = string("11111");
//
//	// 右值引用不能直接引用左值，但是右值引用可以引用move(左值)
//	int&& rrx1 = move(b);
//	int*&& rrx2 = move(p);
//	int&& rrx3 = move(*p);
//	string&& rrx4 = move(s);
//	//move的本质是强制类型转换
//	string&& rrx5 = (string&&)s;
//
//	// b、r1、rr1都是变量表达式，都是左值
//	cout << &b << endl;
//	cout << &r1 << endl;
//	cout << &rr1 << endl;
//
//	//int i = 1;
//	//int* ptr = (int*)i;
//
//	//int&& rr1 = 10;
//	//这里要注意的是，rr1的属性是左值，所以不能再被右值引用绑定，除非move一下
//	int& r6 = rr1;
//
//	//int&& rrx6 = rr1;
//	int&& rrx6 = move(rr1);
//
//}
//
////void f(int& x)
////{
////	cout << "左值引用重载 f(" << x << ")\n";
////}
////
////void f(const int& x)
////{
////	cout << "到 const 的左值引用重载 f(" << x << ")\n";
////}
////
////void f(int&& x)
////{
////	cout << "右值引用重载 f(" << x << ")\n";
////}
////
////void test03()
////{
////	//int&& rr1 = 10;
////	//int a = 20;
////	//int& r2 = a;
////
////	int i = 1;
////	const int ci = 2;
////
////	f(i); // 调用 f(int&)
////	f(ci); // 调用 f(const int&)
////	f(3); // 调用 f(int&&)，如果没有 f(int&&) 重载则会调用 f(const int&)
////	f(std::move(i)); // 调用 f(int&&)
////	cout << endl;
////
////	// 右值引用变量在用于表达式时是左值
////	// 右值引用本身的属性是左值
////	int&& x = 1;
////	f(x); // 调用 f(int& x)
////	f(std::move(x)); // 调用 f(int&& x)
////}
//
////namespace mihayou
////{
////	class string
////	{
////	public:
////		typedef char* iterator;
////		typedef const char* const_iterator;
////
////		iterator begin()
////		{
////			return _str;
////		}
////
////		iterator end()
////		{
////			return _str + _size;
////		}
////
////		const_iterator begin() const
////		{
////			return _str;
////		}
////
////		const_iterator end() const
////		{
////			return _str + _size;
////		}
////
////		string(const char* str = "")
////			:_size(strlen(str))
////			, _capacity(_size)
////		{
////			cout << "string(char* str)-构造" << endl;
////			_str = new char[_capacity + 1];
////			strcpy(_str, str);
////		}
////
////		// 拷贝构造
////		string(const string& s)
////			:_str(nullptr)
////		{
////			cout << "string(const string& s) -- 拷贝构造" << endl;
////			reserve(s._capacity);
////			for (auto ch : s)
////			{
////				push_back(ch);
////			}
////		}
////
////		void swap(string& ss)
////		{
////			::swap(_str, ss._str);
////			::swap(_size, ss._size);
////			::swap(_capacity, ss._capacity);
////		}
////
////		// 移动构造
////		string(string&& s)
////		{
////			cout << "string(string&& s) -- 移动构造" << endl;
////			// 转移掠夺你的资源
////			swap(s);
////		}
////
////		string& operator=(const string& s)
////		{
////			cout << "string& operator=(const string& s) -- 拷贝赋值" <<
////				endl;
////			if (this != &s)
////			{
////				_str[0] = '\0';
////				_size = 0;
////				reserve(s._capacity);
////				for (auto ch : s)
////				{
////					push_back(ch);
////				}
////			}
////			return *this;
////		}
////
////		// 移动赋值
////		string& operator=(string&& s)
////		{
////			cout << "string& operator=(string&& s) -- 移动赋值" << endl;
////			swap(s);
////			return *this;
////		}
////
////		~string()
////		{
////			//cout << "~string() -- 析构" << endl;
////			delete[] _str;
////			_str = nullptr;
////		}
////
////		char& operator[](size_t pos)
////		{
////			assert(pos < _size);
////			return _str[pos];
////		}
////
////		void reserve(size_t n)
////		{
////			if (n > _capacity)
////			{
////				char* tmp = new char[n + 1];
////				if (_str)
////				{
////					strcpy(tmp, _str);
////					delete[] _str;
////				}
////				_str = tmp;
////				_capacity = n;
////			}
////		}
////
////		void push_back(char ch)
////		{
////			if (_size >= _capacity)
////			{
////				size_t newcapacity = _capacity == 0 ? 4 : _capacity * 2;
////				reserve(newcapacity);
////			}
////			_str[_size] = ch;
////			++_size;
////			_str[_size] = '\0';
////		}
////
////		string& operator+=(char ch)
////		{
////			push_back(ch);
////			return *this;
////		}
////
////		const char* c_str() const
////		{
////			return _str;
////		}
////
////		size_t size() const
////		{
////			return _size;
////		}
////	private:
////		char* _str = nullptr;
////		size_t _size = 0;
////		size_t _capacity = 0;
////	};
////}
////
////class Solution {
////public:
////	// 传值返回需要拷贝
////	mihayou::string addStrings(mihayou::string num1, mihayou::string num2) {
////		mihayou::string str;
////		int end1 = (int)num1.size() - 1;
////		int end2 = (int)num2.size() - 1;
////		// 进位
////		int next = 0;
////		while (end1 >= 0 || end2 >= 0)
////		{
////			int val1 = end1 >= 0 ? num1[end1--] - '0' : 0;
////			int val2 = end2 >= 0 ? num2[end2--] - '0' : 0;
////			int ret = val1 + val2 + next;
////			next = ret / 10;
////			ret = ret % 10;
////			str += ('0' + ret);
////		}
////		if (next == 1)
////			str += '1';
////		reverse(str.begin(), str.end());
////		cout << &str << endl;
////
////		return str;
////	}
////};
////
////void test04()
////{
////	mihayou::string ret = Solution().addStrings("11111111111111111111", "222222222222222222222222222");
////
////	//mihayou::string ret;
////	//// ...
////	//ret = Solution().addStrings("11111111111111111111", "222222222222222222222222222");
////	cout << ret.c_str() << endl;
////	cout << &ret<< endl;
////}
////
////void test05()
////{
////	//string ret = Solution().addStrings("11111111111111111111", "222222222222222222222222222");
////	//cout << ret << endl;
////
////	mihayou::string s1("11111111111111111");
////
////	mihayou::string s3 = s1;
////	mihayou::string s4 = mihayou::string("222222222");
////	mihayou::string s5 = move(s1);
////}
//
//void test06()
//{
//	//右值引用延长生命周期
//	Date&& d = Date(10);
//	cout << "111";
//	cout << d._year << " " << d._month << " " << d._day << endl;
//	//Date(100);
//
//	cout << "111";
//
//}
//
//void test07()
//{
//	//左值引用
//	int a = 10;
//	int& ra = a;
//	//加const 可以引用右值
//	const int& rb = 10;
//
//	//右值引用
//	10;
//	int&& rc = 10;
//	//强制转换或者move可以引用左值
//	int&& rd = (int&&)a;
//	int&& rdd = move(a);
//}
//
//void func(int& x)
//{
//	cout << "左值引用" << endl;
//}
//
//void func(const int& x)
//{
//	cout << "到const 的左值引用" << endl;
//}
//
//void func(int&& x)
//{
//	cout << "右值引用" << endl;
//}
//
//void test08()
//{
//	int a = 1;
//	int& ra = a;
//	const int& rra = a;
//
//	func(ra);
//	func(rra);
//	func(10);
//	func(move(a));
//
//}
//
//namespace mihayou
//{
//	class string
//	{
//	public:
//		typedef char* iterator;
//		typedef const char* const_iterator;
//
//		iterator begin()
//		{
//			return _str;
//		}
//
//		iterator end()
//		{
//			return _str + _size;
//		}
//
//		const_iterator begin() const
//		{
//			return _str;
//		}
//
//		const_iterator end() const
//		{
//			return _str + _size;
//		}
//
//		string(const char* str = "")
//			:_size(strlen(str))
//			, _capacity(_size)
//		{
//			cout << "string(char* str)-构造" << endl;
//			_str = new char[_capacity + 1];
//			strcpy(_str, str);
//		}
//
//		// 拷贝构造
//		string(const string& s)
//			:_str(nullptr)
//		{
//			cout << "string(const string& s) -- 拷贝构造" << endl;
//			reserve(s._capacity);
//			for (auto ch : s)
//			{
//				push_back(ch);
//			}
//		}
//
//		void swap(string& ss)
//		{
//			::swap(_str, ss._str);
//			::swap(_size, ss._size);
//			::swap(_capacity, ss._capacity);
//		}
//
//		// 移动构造
//		string(string&& s)
//		{
//			cout << "string(string&& s) -- 移动构造" << endl;
//			// 转移掠夺你的资源
//			swap(s);
//		}
//
//		string& operator=(const string& s)
//		{
//			cout << "string& operator=(const string& s) -- 拷贝赋值" << endl;
//			if (this != &s)
//			{
//				_str[0] = '\0';
//				_size = 0;
//				reserve(s._capacity);
//				for (auto ch : s)
//				{
//					push_back(ch);
//				}
//			}
//			return *this;
//		}
//
//		// 移动赋值
//		string& operator=(string&& s)
//		{
//			cout << "string& operator=(string&& s) -- 移动赋值" << endl;
//			swap(s);
//			return *this;
//		}
//
//		~string()
//		{
//			//cout << "~string() -- 析构" << endl;
//			delete[] _str;
//			_str = nullptr;
//		}
//
//		char& operator[](size_t pos)
//		{
//			assert(pos < _size);
//			return _str[pos];
//		}
//
//		void reserve(size_t n)
//		{
//			if (n > _capacity)
//			{
//				char* tmp = new char[n + 1];
//				if (_str)
//				{
//					strcpy(tmp, _str);
//					delete[] _str;
//				}
//				_str = tmp;
//				_capacity = n;
//			}
//		}
//
//		void push_back(char ch)
//		{
//			if (_size >= _capacity)
//			{
//				size_t newcapacity = _capacity == 0 ? 4 : _capacity * 2;
//				reserve(newcapacity);
//			}
//			_str[_size] = ch;
//			++_size;
//			_str[_size] = '\0';
//		}
//
//		string& operator+=(char ch)
//		{
//			push_back(ch);
//			return *this;
//		}
//
//		const char* c_str() const
//		{
//			return _str;
//		}
//
//		size_t size() const
//		{
//			return _size;
//		}
//	private:
//		char* _str = nullptr;
//		size_t _size = 0;
//		size_t _capacity = 0;
//	};
//}
//
//class Solution {
//public:
//	// 传值返回需要拷贝
//	mihayou::string addStrings(mihayou::string num1, mihayou::string num2) {
//		mihayou::string str;
//		int end1 = (int)num1.size() - 1;
//		int end2 = (int)num2.size() - 1;
//		// 进位
//		int next = 0;
//		while (end1 >= 0 || end2 >= 0)
//		{
//			int val1 = end1 >= 0 ? num1[end1--] - '0' : 0;
//			int val2 = end2 >= 0 ? num2[end2--] - '0' : 0;
//			int ret = val1 + val2 + next;
//			next = ret / 10;
//			ret = ret % 10;
//			str += ('0' + ret);
//		}
//		if (next == 1)
//			str += '1';
//		reverse(str.begin(), str.end());
//		cout << &str << endl;
//
//		return str;
//	}
//};
//
//void test09()
//{
//	mihayou::string ret = Solution().addStrings("111111", "22222");
//	cout << &ret << endl;
//
//}
//
//void test10()
//{
//	mihayou::string ret;
//	ret = Solution().addStrings("111111", "22222");
//	cout << &ret << endl;
//
//}
//
//template<class T>
//void f1(T& x)
//{
//
//}
//
//template<class T>
//void f2(T&& x)
//{
//
//}
//
//typedef int& lref;
//typedef int&& rref;
//
////右值引用的右值引用折叠成右值引用，所有其他组合均折叠成左值引用
//
//void test11()
//{
//	int a = 1;
//	f1(a);
//
//	int n = 0;
//	//引用折叠
//	lref& r1 = n;//r1的类型是int&
//	lref&& r2 = n;//r2的类型是int&
//
//	rref& r3 = n;//r3的类型是int&
//	rref&& r4 = move(n);//r4的类型是int&& 
//
//	// 没有折叠->实例化为void f1(int& x)
//	f1<int>(n);
//	//f1<int>(0); //error
//
//	// 折叠->实例化为void f1(int& x)
//	f1<int&>(n);
//	//f1<int&>(0); //error
//
//	// 折叠->实例化为void f1(int& x)
//	f1<int&&>(n);
//	//f1<int&&>(0);//error
//
//	// 折叠->实例化为void f1(const int& x)
//	f1<const int&>(n);
//	f1<const int&>(0);
//
//	// 折叠->实例化为void f1(const int& x)
//	f1<const int&&>(n);
//	f1<const int&&>(0);
//
//	// 没有折叠->实例化为void f2(int&& x)
//	//f2<int>(n);//error
//	f2<int>(0);
//
//	// 折叠->实例化为void f2(int& x)
//	f2<int&>(n);
//	//f2<int&>(0);//error
//
//	// 折叠->实例化为void f2(int&& x)
//	//f2<int&&>(n);//error
//	f2<int&&>(0);
//
//}
//
////万能引用
//template<class T>
//void Function(T&& t)
//{
//	int a = 0;
//	T x = a;
//	//++x;
//
//	cout << &a << endl;
//	cout << &x << endl << endl;
//}
//
////右值会推导出int,左值会推导出int&
//
//void test12()
//{
//	// 10是右值，推导出T为int，模板实例化为void Function(int&& t)
//	Function(10);
//
//	int a = 10;
//	// a是左值，推导出T为int&，引用折叠，模板实例化为void Function(int& t)
//	Function(a);
//
//	//move(a)是右值，推导出T为int，模板实例化为void Function(int&& t)
//	Function(move(a));
//
//	const int b = 100;
//	// b是左值，推导出T为const int&，引用折叠，模板实例化为void Function(const int& t)
//	// 所以Function内部会编译报错，x不能+
//	Function(b);
//
//	// move(b)右值，推导出T为const int，模板实例化为void Function(const int&& t)
//	// 所以Function内部会编译报错，x不能++
//	Function(move(b));
//}
//
//
//void fun(int& x)
//{
//	cout << "左值引用" << endl;
//}
//
//void fun(const int& x)
//{
//	cout << "const左值引用" << endl;
//}
//
//void fun(int&& x)
//{
//	cout << "右值引用" << endl;
//}
//
//void fun(const int&& x)
//{
//	cout << "const右值引用" << endl;
//}
//
//template<class T>
//void function(T&& x)
//{
//	fun(forward<T>(x));
//}
//
//void test13()
//{
//	//fun(10);
//	function(10);
//
//
//	int a = 10;
//	/*fun(a);
//	fun(move(a));*/
//	function(a);
//	function(move(a));
//
//	const int b = 20;
//	/*fun(b);
//	fun(move(b));*/
//	function(b);
//	function(move(b));
//
//}
//
////#include "list.h"
////
////void test14()
////{
////	mihayou::list<mihayou::string> lt;
////	mihayou::string s1("11111111111");
////	lt.push_back(s1);
////
////	mihayou::string s2("33333333333");
////	lt.push_back(move(s2));
////
////	lt.push_back("22222222222");
////}
//
//#include "L.h"
//
//void test15()
//{
//	bit::list<mihayou::string> lt;
//	mihayou::string s1("11111111111");
//	lt.push_back(s1);
//
//	mihayou::string s2("33333333333");
//	lt.push_back(move(s2));
//
//	lt.push_back("22222222222");
//}
//
////
//// 可变参数模板
////template<class ...Args>
////void Print(Args... args)
////{
////	cout << sizeof...(args) << endl;
////}
//
////错误的写法：
////template<class ...Args>
////void Print(Args... args)
////{
////	for (size_t i = 0; i < sizeof...(args); i++)
////	{
////		//error C3520: “args”: 必须在此上下文中扩展参数包
////		cout << args[i] << endl;
////	}
////	cout << endl;
////}
//
//
//
////void test16()
////{
////	Print(1);
////	Print("111",1,11.6);
////}
//
//
////包扩展（解析出包的内容）
//void showlist()
//{
//	//编译时递归停止的条件
//	cout << endl;
//	return;
//}
//
//template<class T,class ...Args>
//void showlist(T&& x,Args&&... args)
//{
//	cout << x << endl;
//	showlist(args...);
//}
//
////template<class T,class ...Args>
////void showlist(T&& x,Args&&... args)
////{
//// //运行时递归停止的条件，在这里不能使用
////	if (sizeof...(args) == 0)
////	{
////		return;
////	}
////	cout << x << endl;
////	showlist(args...);
////}
//
//
//template<class ...Args>
//void Print(Args... args)
//{
//	showlist(args...);
//}
//
//void test17()
//{
//	Print();
//	Print(1, 11.1);
//	Print(1, 66.6, "hello");
//}
//
////template<class T>
////const T& getN(const T& x)
////{
////	cout << x << endl;
////	return x;
////}
//
//template<class T>
//int getN(const T& x)
//{
//	cout << x << endl;
//	return 0;
//}
//
//template<class ...Args>
//void Arguments(Args&&... args)
//{
//
//}
//
//
//template<class ...Args>
//void print(Args&&... args)
//{
//	//注意getN()必须返回或者得到的对象，这样才能组成参数包给Arguments
//	Arguments(getN(args)...);
//}
//
////对于print(1, "hello", 66.6);
////Arguments(getN(args)...);可以转换成
////Arguments(getN(1),getN("hello",getN(66.6));
////void getN(const int& x) void getN(const string& x)  void getN(const double& x)
//
//
////void print(int&& x,string&& y,double&& z)
////{
////	Arguments(getN(1), getN("hello"),getN(66.6));
////}
//
//void test18()
//{
//	print();
//	print(1);
//	print(1, "hello", 66.6);
//}
//
//#include <list>
//
//void test19()
//{
//	list<mihayou::string> lt;
//	mihayou::string s1("hello");
//	mihayou::string s2("world");
//
//	//传左值
//	lt.emplace_back(s1);
//	cout << "********************" << endl;
//	lt.push_back(s1);
//	cout << endl;
//
//	//传右值
//	lt.emplace_back(move(s1));
//	cout << "********************" << endl;
//	lt.push_back(move(s2));
//	cout << endl;
//
//	lt.emplace_back("1111");
//	cout << "********************" << endl;
//	lt.push_back("6");
//
//
//}
//
//void test20()
//{
//	list<pair<mihayou::string, int>> lt;
//
//	//lt.emplace_back({ "你好", 6 });//不支持
//	lt.emplace_back("你好", 6);
//
//	cout << "********************" << endl;
//	lt.push_back({ "世界", 8 });
//
//}
//
//
//// lambda表达式语法
////lambda 表达式本质是⼀个匿名函数对象，跟普通函数不同的是他可以定义在函数内部
//
//void test21()
//{
//	//[capture-list] (parameters)-> return type {function boby}
//	//捕捉列表          参数列表          返回值类型   函数体
//	// 1、捕捉为空也不能省略
//	// 2、参数为空可以省略
//	// 3、返回值可以省略，可以通过返回对象自动推导
//	// 4、函数体不能省略
//
//	auto add1 = [](int x, int y) ->int { return x + y; };
//	cout << add1(1, 6) << endl;
//
//	auto f1 = []
//		{
//			cout << "hello world" << endl;
//			return 0;
//		};
//
//	f1();
//
//
//}
//
//#include<algorithm>
//
//struct Goods
//{
//	string _name;  // 名字
//	double _price; // 价格
//	int _evaluate; // 评价
//	// ...
//
//	Goods(const char* str, double price, int evaluate)
//		:_name(str)
//		, _price(price)
//		, _evaluate(evaluate)
//	{}
//};
//
//struct Compare1
//{
//	bool operator()(const Goods& gl, const Goods& gr)
//	{
//		return gl._price < gr._price;
//	}
//};
//
//struct Compare2
//{
//	bool operator()(const Goods& gl, const Goods& gr)
//	{
//		return gl._price > gr._price;
//	}
//};
//
//void test22()
//{
//	vector<Goods> v = { { "苹果", 2.1, 5 }, { "香蕉", 3, 4 }, { "橙子", 2.2, 3}, { "菠萝", 1.5, 4 } };
//	// 类似这样的场景，我们实现仿函数对象或者函数指针支持商品中
//	// 不同项的比较，相对还是比较麻烦的，那么这里lambda就很好用了
//
//	// 价格升序
//	sort(v.begin(), v.end(), Compare1());
//
//	// 价格降序
//	sort(v.begin(), v.end(), Compare2());
//
//	sort(v.begin(), v.end(), [](const Goods& g1, const Goods& g2) {
//		return g1._price < g2._price;
//		});
//
//	sort(v.begin(), v.end(), [](const Goods& g1, const Goods& g2) {
//		return g1._price > g2._price;
//		});
//
//	sort(v.begin(), v.end(), [](const Goods& g1, const Goods& g2) {
//		return g1._evaluate < g2._evaluate;
//		});
//
//	sort(v.begin(), v.end(), [](const Goods& g1, const Goods& g2) {
//		return g1._evaluate > g2._evaluate;
//		});
//
//}
//
//int k = 6;
//
//auto func0 = []
//	{
//		return k;
//	};
//
//
//void test23()
//{
//	int a = 1;
//	int b = 4;
//	int c = 6;
//	int d = 8;
//	//只能用当前lambda局部域和捕捉的对象和全局对象
//	//这里的&b是引用
//	auto func1 = [a, &b](int x)
//		{
//			//值捕捉的变量不能修改，引用捕捉的变量可以修改
//			//a++;
//			b++;
//			return a + b + x;
//		};
//	cout << func1(2) << endl;
//
//	auto func2 = [a, &b](int x) mutable
//		{
//			//加了mutable,对于值捕捉的变量可以进行修改，但是不影响外面的变量(a)
//			a++;
//			b++;
//			return a + b + x;
//		};
//	cout << func2(6) << endl;
//	cout << a << endl;
//
//	// 隐式值捕捉
//	// 用了哪些变量就捕捉哪些变量
//	auto func3 = [=](int x)
//		{
//			//a++;
//			//c++;
//			return a + x + c;
//		};
//	cout << func3(1) << endl;
//	// 隐式引用捕捉
//	// 用了哪些变量就捕捉哪些变量
//	auto func4 = [&](int x)
//		{
//			b++;
//			d++;
//			return b + d + x;
//		};
//	cout << func4(2) << endl;
//	cout << a << " " << b << " " << c << " " << d << endl;
//
//	//混合捕捉
//	auto func5 = [=, &a, &b](int x)
//		{
//			a++;
//			b++;
//			//c++;
//			return a + b + c + x;
//		};
//	cout << func5(1) << endl;
//
//	//混合捕捉
//	auto func6 = [&, b, c]
//		{
//			a++;
//			//b++;
//			return a + b + c;
//		};
//	cout << func6() << endl;
//
//	static const int kk = 1;
//	//全局变量与静态变量不需要捕捉
//	auto func7 = []
//		{
//			return k + kk;
//		};
//	cout << func7() << endl;
//
//	cout << func0() << endl;
//}
//
//class Rate
//{
//public:
//	Rate(double rate)
//		: _rate(rate)
//	{}
//	double operator()(double money, int year)
//	{
//		return money * _rate * year;
//	}
//private:
//	double _rate;
//};
//
//void test24()
//{
//	double rate = 0.49;
//
//	// lambda
//	auto r2 = [rate](double money, int year) {
//		return money * rate * year;
//	};
//	
//	// 函数对象
//	Rate r1(rate);
//	r1(10000, 2);
//	r2(10000, 2);
//	
//	auto func1 = [] {
//		cout << "hello world" << endl;
//	};
//	
//	func1();
// }
//
//class Person
//{
//public:
//	Person(const char* name = "张三", int age = 1)
//		:_name(name)
//		, _age(age)
//	{}
//
//	Person(const Person& p) = default;
//	Person(Person&& p) = default;
//
//
//	~Person()
//	{}
//private:
//	mihayou::string _name;
//	int _age;
//};
//
//void func(ostream& out)
//{}
//
//
//void test25()
//{
//	Person s1;
//	Person s2 = s1;
//	Person s3 = std::move(s1);
//	
//	Person s4;
//	//s4 = std::move(s2);
//	
//	func(cout);
//}
//
#include <functional>
// function

//template <class T>
//class function; // undefined
//template <class Ret, class... Args>
//class function<Ret(Args...)>;

int f(int a,int b)
{
	return a + b;
}

struct Functor
{
public:
	int operator() (int a, int b)
	{
		return a + b;
	}
};

class Plus
{
public:
	Plus(int n = 10)
		:_n(n)
	{}

	static int plusi(int a, int b)
	{
		return a + b;
	}

	double plusd(double a, double b)
	{
		return (a + b) * _n;
	}

private:
	int _n;
};
//
void test26()
{
	// 包装各种可调用对象
	//  <返回值(参数1，参数2...)>
	function<int(int, int)> f1 = f;
	function<int(int, int)> f2 = Functor();
	function<int(int, int)> f3 = [](int a, int b) {return a + b; };
	cout << f1(1, 1) << endl;
	cout << f2(1, 1) << endl;
	cout << f3(1, 1) << endl;

	// 包装静态成员函数
	// 成员函数要指定类域并且前面加&才能获取地址

	function<int(int, int)> f4 = Plus::plusi;
	cout << f4(1, 1) << endl;
	
	function<double(Plus*,double, double)> f5 = &Plus::plusd;
	Plus pl;
	cout << f5(&pl,1, 1) << endl;

	function<double(Plus, double, double)> f6 = &Plus::plusd;
	cout << f6(pl, 1, 1) << endl;
	cout << f6(Plus(), 1, 1) << endl;

	function<double(Plus&&, double, double)> f7 = &Plus::plusd;
	cout << f7(move(pl), 1, 1) << endl;
	//cout << f7(pl, 1, 1) << endl;

	

}

//bind 
//bind 调整参数个数与参数顺序

using placeholders::_1;
using placeholders::_2;
using placeholders::_3;

int Sub(int a, int b)
{
	return (a - b) * 10;
}

int SubX(int a, int b, int c)
{
	return (a - b - c) * 10;
}

void test27()
{
	auto sub1 = bind(Sub, _1, _2);
	cout << sub1(10, 5) << endl;

	auto sub2 = bind(Sub, _2, _1);
	cout << sub2(10, 5) << endl;

	//调整参数个数，经常使用
	auto sub3 = bind(Sub, 100, _1);
	//这个_1是参数的顺序是5
	cout << sub3(5) << endl;

	auto sub4 = bind(Sub, _1, 100);
	cout << sub4(5) << endl;

	//分别绑死第123个参数
	auto sub5 = bind(SubX, 100, _1, _2);
	cout << sub5(5, 1) << endl;

	auto sub6 = bind(SubX, _1, 100, _2);
	cout << sub6(5, 1) << endl;

	auto sub7 = bind(SubX, _1, _2, 100);
	cout << sub7(5, 1) << endl;

	// 成员函数对象进行绑死，就不需要每次都传递了
	function<double(Plus&&, double, double)> f6 = &Plus::plusd;
	Plus pd;
	cout << f6(move(pd), 1.1, 1.1) << endl;
	cout << f6(Plus(), 1.1, 1.1) << endl;

	// 计算复利的lambda
	// 复利前一年的利息变成第二年本金
	// (10000*0.02 + 10000)*0.02 + 10000*0.02 + 10000
	// 利率  本金  年限
	auto func1 = [](double rate, double money, int year)->double
		{
			double ret = money;
			for (int i = 0; i < year; i++)
			{
				ret += ret * rate;
			}
			return ret - money;
		};

	//cout << func1(0.05, 10000000, 30) << endl;


	// 绑死一些参数，实现出支持不同年华利率，不同金额和不同年份计算出复利的结算利息
	function<double(double)> func3_1_5 = bind(func1, 0.015, _1, 3);
	function<double(double)> func5_1_5 = bind(func1, 0.015, _1, 5);
	function<double(double)> func10_1_5 = bind(func1, 0.015, _1, 10);

	function<double(double)> func3_2_5 = bind(func1, 0.025, _1, 3);
	function<double(double)> func5_2_5 = bind(func1, 0.025, _1, 5);
	function<double(double)> func10_2_5 = bind(func1, 0.025, _1, 10);

	cout << func3_1_5(1000000) << endl;
	cout << func5_1_5(1000000) << endl;
	cout << func10_1_5(1000000) << endl;

	cout << func3_2_5(1000000) << endl;
	cout << func5_2_5(1000000) << endl;
	cout << func10_2_5(1000000) << endl;


}

#include "list.h"

//using 新的名字 = 老的名字
//typedef 老的名字  新的名字

void test28()
{
	//typedef list<int> list;
	list<int> l1;
	using ls = list<int>;

	ls l2;
}

class Date
{
public:
	Date(int year = 1, int month = 1, int day = 1)
		:_year(year),
		_month(month),
		_day(day)
	{
		cout << "Date(int year, int month, int day)" << endl;
	}

	Date(const Date& d)/* = delete*/
	{
		_year = d._year;
		_month = d._month;
		_day = d._day;
		cout << "Date(const Date& d)" << endl;
	}

	Date& operator=(const Date& d) = delete;

	~Date()
	{
		cout << "~Date() " << endl;

	}

//private:
	int _year;
	int _month;
	int _day;
};


void test29()
{
	Date d1;
	Date d2(d1);
	Date d3;
	//error
	//d3 = d1;

}

int main()
{
	test29();
	return 0;
}
